local header = [[
..\Base.simc

report_details=0

gear_expertise_rating=2551
gear_hit_rating=2551

default_actions=1
]]

local base_profiles = {
	"Hunter_BM_T16H",
	"Hunter_SV_T16H",
	"Hunter_MM_T16H",
}

dofile([[..\lib_simc_lua.lua]])
-- local func = loadfile([[..\lib_simc_lua.lua]])
-- if func then
-- 	print("Loading library ...")
-- 	func()
-- end

function get_rating_from_log( crit, haste )
	local total_dps, total_sqerr, total_iteration = 0, 0, 0
	-- log("\tFetching rating for (%d, %d) ...", crit, haste)
	for index, profile in ipairs(session.profiles) do
		if profile.crit == crit and profile.haste == haste then
			-- log("\t\tfound profile #%d: %d - %d @%d", index, profile.dps, profile.err, profile.iterations)
			total_dps = total_dps + profile.dps * profile.iterations
			total_sqerr = total_sqerr + (profile.err ^ 2) * profile.iterations * profile.iterations
			total_iteration = total_iteration + profile.iterations
		end
	end
	if total_iteration > 0 then
		local dps = total_dps / total_iteration
		local err = math.sqrt(total_sqerr / (total_iteration ^ 2))
		-- log("\tExisting rating at (%d, %d): %d - %d @%d", crit, haste, dps, err, total_iteration)
		return dps, err, total_iteration
	else
		return 0, 0, 0
	end
end

function estimate_iteration( iterations, err, required_err )
	local sqerr = err * (iterations ^ 2)
	return (sqerr / required_err) ^ 2
end

function estimate_err( iterations, err, iterations_given )
	--log("\testimating from %d @%d to @%d", err, iterations, iterations_given)
	local sqerr = err * math.sqrt(iterations)
	return sqerr / math.sqrt(iterations_given)
end

function calc_rating( node, iterations )
	node.iterations = iterations
	session.iterations = iterations
	local elapsed, simcElapsed = process_profile(node, #session.profiles + 1)
	if elapsed > 0 then
		log("\t\tSim #%d took time %.3f / %.3f (%.2f%%)", #session.profiles + 1, simcElapsed, elapsed, simcElapsed / elapsed * 100)
	end
	table.insert(session.profiles, node)
	save_session()
	return node
end

function new_node( crit, haste )
	local mastery = session.total_stat - crit - haste
	if crit < session.min_stat then
		return log("Crit below min limit")
	elseif haste < session.min_stat then
		return log("Haste below min limit")
	elseif mastery < session.min_stat then
		return log("Mastery below min limit")
	else
		return {
			crit = crit,
			haste = haste,
			profile = ("gear_crit_rating=%d\ngear_haste_rating=%d\ngear_mastery_rating=%d\n"):format(
				crit,
				haste,
				mastery
			),
		}
	end
end

function calc_node_rating( crit, haste, iterations )
	log("\tStart rating for (%d, %d) @%d", crit, haste, iterations)
	local node = new_node(crit, haste)
	if not node then
		return
	end
	local prev_dps, prev_err, prev_iterations = get_rating_from_log(crit, haste)
	if prev_iterations > 0 then
		log("\t\tFetched dps: %d - %d @%d", prev_dps, prev_err, prev_iterations)
		-- iterations = iterations - prev_iterations
	end
	if iterations - prev_iterations > 0 then
		log("\t\tCalculating for (%d, %d) @%d (need %d, got %d)", crit, haste, iterations - prev_iterations, iterations, prev_iterations)
		calc_rating(node, iterations - prev_iterations)
		local dps, err, iterations = get_rating_from_log(crit, haste)
		log("\t\tRating (%d, %d) : %d - %d @%d", crit, haste, dps, err, iterations)
		return {
			crit = node.crit,
			haste = node.haste,
			dps = dps,
			err = err,
			iterations = iterations,
		}
	else
		-- log("Skipped node (%d, %d) @%d: got enough sample: %d", crit, haste, iterations, prev_iterations)
		log("\t\tRating (%d, %d) : %d - %d @%d", crit, haste, prev_dps, prev_err, prev_iterations)
		return {
			crit = node.crit,
			haste = node.haste,
			dps = prev_dps,
			err = prev_err,
			iterations = prev_iterations,
		}
	end
end

function calc_neighbour_rating( node, crit, haste, iterations )
	local prev_node = calc_node_rating(crit, haste, 0)
	if may_climb_node(node, prev_node) then
		return calc_node_rating(crit, haste, iterations)
	else
		return prev_node
	end
end

function calc_neighbours( node, delta, iterations )
	node.crit_p = calc_neighbour_rating(node, node.crit + delta, node.haste, iterations)
	node.crit_n = calc_neighbour_rating(node, node.crit - delta, node.haste, iterations)
	node.haste_p = calc_neighbour_rating(node, node.crit, node.haste + delta, iterations)
	node.haste_n = calc_neighbour_rating(node, node.crit, node.haste - delta, iterations)
--	node.crit_p = calc_node_rating(node.crit + delta, node.haste, iterations)
--	node.crit_n = calc_node_rating(node.crit - delta, node.haste, iterations)
--	node.haste_p = calc_node_rating(node.crit, node.haste + delta, iterations)
--	node.haste_n = calc_node_rating(node.crit, node.haste - delta, iterations)
end

local neighbour_keys = {"crit_p", "crit_n", "haste_p", "haste_n"}
function sort_neighbours( node )
	node.neighbours = {}
	for index, key in ipairs( neighbour_keys ) do
		if node[key] and node[key].dps then
			node[key].direction = key
			table.insert(node.neighbours, node[key])
		end
	end
	table.sort(node.neighbours,
		function(node1, node2)
			return node1.dps > node2.dps
		end
	)
	save_session()
end

function may_climb_node( nodeBase, nodeDest )
	if not nodeDest or nodeDest.iterations <= 0 then
		return true
	end
	local est_err_base = estimate_err(nodeBase.iterations, nodeBase.err, session.max_iterations)
	local est_err_dest = estimate_err(nodeDest.iterations, nodeDest.err, session.max_iterations)
	local gain = nodeDest.dps - nodeBase.dps

	--nodeDest.dps + est_err_dest > nodeBase.dps - est_err_base
	--err > -gain
	if 0.3 * (est_err_base + est_err_dest) > gain and nodeBase.iterations >= session.base_iterations and nodeDest.iterations >= session.base_iterations then
		return false
	end
	return true
end

function get_highest_neighbour( node, delta, iterations )
	calc_neighbours(node, delta, iterations)
	sort_neighbours(node)
	-- log("\tNeighbours sorted:")
	for index, node in ipairs(node.neighbours) do
		-- log("\t\t%s\t%d", node.direction, node.dps)
	end
end

function try_climb_dest(delta, iterations)
	log("---Try climb dest delta %d @%d---", delta, iterations)
	if delta < session.min_delta then
		return log("\tDelta %d below limit %d", delta, session.min_delta)
	elseif delta > session.max_delta then
		return log("\tDelta %d above limit %d", delta, session.max_delta)
	end
	local iterations = iterations
	if iterations > session.max_iterations then
		log("\tIterations %d above limit %d", iterations, session.max_iterations)
		iterations = session.max_iterations
	elseif iterations < session.base_iterations / 2 then
		log("\tIterations %d below limit %d", iterations, session.base_iterations / 2)
		iterations = session.base_iterations / 2
	end

	--local disabled_deltas = session.current_node.disabled_deltas
	--if disabled_deltas and disabled_deltas[delta] then
	--	return
	--end

	log("Rating current node ...")
	session.current_node = calc_node_rating(session.current_node.crit, session.current_node.haste, iterations)
	--session.current_node.disabled_deltas = disabled_deltas

	get_highest_neighbour(session.current_node, delta, iterations)

	local highest_node = session.current_node.neighbours[1]
	if highest_node then
		local gain = highest_node.dps - session.current_node.dps
		local err = highest_node.err + session.current_node.err
		if gain > session.err_multiplier * err then
			log("---Neighbour %s extinctively higher than current node: %d (%d - %d) > %d, %.1f * %d (%d + %d)", highest_node.direction, gain, highest_node.dps, session.current_node.dps, session.err_multiplier * err, session.err_multiplier, err, highest_node.err, session.current_node.err)
			session.current_node = highest_node
			session.prev_iterations = iterations
			session.delta = delta
			return true
		else
			log("---Highest neighbour %s %d (%d - %d) < %d (%d + %d)", highest_node.direction, gain, highest_node.dps, session.current_node.dps, err, highest_node.err, session.current_node.err)
--			local est_err_current = estimate_err(session.current_node.iterations, session.current_node.err, session.max_iterations)
--			local est_err_highest = estimate_err(highest_node.iterations, highest_node.err, session.max_iterations)
--
--			log("\test err - %d - %d", est_err_current, est_err_highest)
--			if 0.3 * (est_err_current + est_err_highest) > gain and iterations >= session.base_iterations then
--				session.current_node.disabled_deltas = session.current_node.disabled_deltas or {}
--				session.current_node.disabled_deltas[delta] = true
--				log("---Disabled further calc on (%d, %d) delta %d: est err - %d - %d", session.current_node.crit, session.current_node.haste, delta, est_err_current, est_err_highest)
--			else
--		-- elseif math.abs(gain) <= err then
--			end
		end
	end
end

function try_climb(err_multiplier)
	log("---Try climb err margin %.2f ---", err_multiplier)
	session.err_multiplier = err_multiplier
	local iterations = session.prev_iterations or session.base_iterations
	local delta = session.delta or 2000
	return
		try_climb_dest(delta	, iterations / 4)	or
		try_climb_dest(delta	, iterations / 2)	or
		try_climb_dest(delta	, iterations	)	or
		try_climb_dest(delta	, iterations * 2)	or

		try_climb_dest(delta / 2, iterations / 4)	or
		try_climb_dest(delta / 2, iterations / 2)	or
		try_climb_dest(delta / 2, iterations	)	or
		try_climb_dest(delta / 2, iterations * 2)	or

		try_climb_dest(delta	, iterations * 4)	or
		try_climb_dest(delta / 2, iterations * 4)	or

		try_climb_dest(delta / 4, iterations / 4)	or
		try_climb_dest(delta / 4, iterations / 2)	or
		try_climb_dest(delta / 4, iterations	)	or

		try_climb_dest(delta * 2, iterations / 4)	or
		try_climb_dest(delta * 2, iterations / 2)	or
		try_climb_dest(delta * 2, iterations	)	or
		try_climb_dest(delta * 2, iterations * 2)	or

		try_climb_dest(delta * 2, iterations * 4)	or
		try_climb_dest(delta	, iterations * 8)	or
		try_climb_dest(delta / 2, iterations * 8)	or
		try_climb_dest(delta * 2, iterations * 8)	or

		try_climb_dest(delta / 4, iterations * 2)	or
		try_climb_dest(delta / 4, iterations * 4)	or
		try_climb_dest(delta / 4, iterations * 8)	or

		try_climb_dest(delta / 2, iterations * 16)	or
		try_climb_dest(delta / 4, iterations * 16)	or
		false
end

function climb_surf(start_crit, start_haste, total_stat)
	log("=== Starting process from (%d, %d) %d total ===", start_crit, start_haste, total_stat)
	-- log("Using baseChar %s", baseChar)
	if session.total_stat ~= total_stat then
		session.total_stat = total_stat
		session.current_node = {
			crit = start_crit,
			haste = start_haste,
		}
	end

	repeat
		local ret = try_climb(0.7) or try_climb(0.5) or try_climb(0.3)
	until not ret

	local crit = session.current_node.crit
	local haste = session.current_node.haste
	local mastery = session.total_stat - crit - haste
	log("=== Finished processing at (%d, %d, %d) (delta %d) @%d ===", crit, haste, mastery, session.delta, session.prev_iterations or session.base_iterations)
	return session.current_node
end

------------------------------------------------------------------------------

session = {
	profiles = {},
}

session.name = ...

if not session.name then
	for index, value in ipairs( base_profiles ) do
		print(index, value)
	end
	print("Session name:")
	io.stdin:flush()
	session.name = io.stdin:read("*l") or "DefaultSession"
end

if tonumber(session.name) then
	session.baseChar = base_profiles[tonumber(session.name)]
	session.name = session.baseChar
	print("Using base profile", session.baseChar)
else
	print("Base profile:")
	io.stdin:flush()
	session.baseChar = io.stdin:read("*l")
end

local func = loadfile([[Sessions\]] .. session.name .. [[.lua]])
if func then
	log("Loading session from file ...")
	func()
end

session.log_file = io.open([[Sessions\]] .. session.name .. [[.log]], "a+")

session.header = header

save_session()

session.result = session.result or {}

local stat_profiles = {
---[[
	{ 40000, 4000, 4000, },
	{ 39500, 4000, 4000, },
	{ 39000, 4000, 4000, },
	{ 38500, 4000, 4000, },
	{ 38000, 4000, 4000, },
	{ 37500, 4000, 4000, },
	{ 37000, 4000, 4000, },
	{ 36500, 4000, 4000, },
	{ 36000, 4000, 4000, },
	{ 35500, 4000, 4000, },
	{ 35000, 4000, 4000, },
	{ 34500, 4000, 4000, },
	{ 34000, 4000, 4000, },
	{ 33500, 4000, 4000, },
	{ 33000, 4000, 4000, },
	{ 32500, 4000, 4000, },
	{ 32000, 4000, 4000, },
	{ 31500, 4000, 4000, },
	{ 31000, 4000, 4000, },
	{ 30500, 4000, 4000, },
	{ 30000, 4000, 4000, },
	{ 29500, 4000, 4000, },
	{ 29000, 4000, 4000, },
	{ 28500, 4000, 4000, },
	{ 28000, 4000, 4000, },
	{ 27500, 4000, 4000, },
	{ 27000, 4000, 4000, },
	{ 26500, 4000, 4000, },
	{ 26000, 4000, 4000, },
	{ 25500, 4000, 4000, },
	{ 25000, 4000, 4000, },
	{ 24500, 4000, 4000, },
	{ 24000, 4000, 4000, },
	{ 23500, 4000, 4000, },
	{ 23000, 4000, 4000, },
	{ 22500, 4000, 4000, },
	{ 22000, 4000, 4000, },
	{ 21500, 4000, 4000, },
	{ 21000, 4000, 4000, },
	{ 20500, 4000, 4000, },
	{ 20000, 4000, 4000, },

	{ 40000, 4000, 16000, },
	{ 39500, 4000, 16000, },
	{ 39000, 4000, 16000, },
	{ 38500, 4000, 16000, },
	{ 38000, 4000, 16000, },
	{ 37500, 4000, 16000, },
	{ 37000, 4000, 16000, },
	{ 36500, 4000, 16000, },
	{ 36000, 4000, 16000, },
	{ 35500, 4000, 16000, },
	{ 35000, 4000, 16000, },
	{ 34500, 4000, 16000, },
	{ 34000, 4000, 16000, },
	{ 33500, 4000, 16000, },
	{ 33000, 4000, 16000, },
	{ 32500, 4000, 16000, },
	{ 32000, 4000, 16000, },
	{ 31500, 4000, 16000, },
	{ 31000, 4000, 16000, },
	{ 30500, 4000, 16000, },
	{ 30000, 4000, 16000, },
	{ 29500, 4000, 16000, },
	{ 29000, 4000, 16000, },
	{ 28500, 4000, 16000, },
	{ 28000, 4000, 16000, },
	{ 27500, 4000, 16000, },
	{ 27000, 4000, 16000, },
	{ 26500, 4000, 16000, },
	{ 26000, 4000, 16000, },
	{ 25500, 4000, 16000, },
	{ 25000, 4000, 16000, },
	{ 24500, 4000, 16000, },
	{ 24000, 4000, 16000, },
	{ 23500, 4000, 16000, },
	{ 23000, 4000, 16000, },
	{ 22500, 4000, 16000, },
	{ 22000, 4000, 16000, },
	{ 21500, 4000, 16000, },
	{ 21000, 4000, 16000, },
	{ 20500, 4000, 16000, },
	{ 20000, 4000, 16000, },

	{ 40000, 16000, 4000, },
	{ 39500, 16000, 4000, },
	{ 39000, 16000, 4000, },
	{ 38500, 16000, 4000, },
	{ 38000, 16000, 4000, },
	{ 37500, 16000, 4000, },
	{ 37000, 16000, 4000, },
	{ 36500, 16000, 4000, },
	{ 36000, 16000, 4000, },
	{ 35500, 16000, 4000, },
	{ 35000, 16000, 4000, },
	{ 34500, 16000, 4000, },
	{ 34000, 16000, 4000, },
	{ 33500, 16000, 4000, },
	{ 33000, 16000, 4000, },
	{ 32500, 16000, 4000, },
	{ 32000, 16000, 4000, },
	{ 31500, 16000, 4000, },
	{ 31000, 16000, 4000, },
	{ 30500, 16000, 4000, },
	{ 30000, 16000, 4000, },
	{ 29500, 16000, 4000, },
	{ 29000, 16000, 4000, },
	{ 28500, 16000, 4000, },
	{ 28000, 16000, 4000, },
	{ 27500, 16000, 4000, },
	{ 27000, 16000, 4000, },
	{ 26500, 16000, 4000, },
	{ 26000, 16000, 4000, },
	{ 25500, 16000, 4000, },
	{ 25000, 16000, 4000, },
	{ 24500, 16000, 4000, },
	{ 24000, 16000, 4000, },
	{ 23500, 16000, 4000, },
	{ 23000, 16000, 4000, },
	{ 22500, 16000, 4000, },
	{ 22000, 16000, 4000, },
	{ 21500, 16000, 4000, },
	{ 21000, 16000, 4000, },
	{ 20500, 16000, 4000, },
	{ 20000, 16000, 4000, },

	{ 40000, 15000, 15000, },
	{ 39500, 15000, 15000, },
	{ 39000, 15000, 15000, },
	{ 38500, 15000, 15000, },
	{ 38000, 15000, 15000, },
	{ 37500, 15000, 15000, },
	{ 37000, 15000, 15000, },
	{ 36500, 15000, 15000, },
	{ 36000, 15000, 15000, },
	{ 35500, 15000, 15000, },
	{ 35000, 15000, 15000, },
	{ 34500, 15000, 15000, },
	{ 34000, 15000, 15000, },
	{ 33500, 15000, 15000, },
	{ 33000, 15000, 15000, },
	{ 32500, 15000, 15000, },
	{ 32000, 15000, 15000, },
	{ 31500, 15000, 15000, },
	{ 31000, 15000, 15000, },
	{ 30500, 15000, 15000, },
	{ 30000, 10000, 10000, },
	{ 29500, 10000, 10000, },
	{ 29000, 10000, 10000, },
	{ 28500, 10000, 10000, },
	{ 28000, 10000, 10000, },
	{ 27500, 10000, 10000, },
	{ 27000, 10000, 10000, },
	{ 26500, 10000, 10000, },
	{ 26000, 10000, 10000, },
	{ 25500, 10000, 10000, },
	{ 25000, 10000, 10000, },
	{ 24500, 10000, 10000, },
	{ 24000, 10000, 10000, },
	{ 23500, 10000, 10000, },
	{ 23000, 10000, 10000, },
	{ 22500, 10000, 10000, },
	{ 22000, 10000, 10000, },
	{ 21500, 10000, 10000, },
	{ 21000, 10000, 10000, },
	{ 20500, 10000, 10000, },
	{ 20000, 10000, 10000, },
--]]
--[[
	{ 40000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 39500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 39000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 38500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 38000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 37500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 37000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 36500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 36000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 35500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 35000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 34500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 34000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 33500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 33000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 32500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 32000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 31500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 31000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 30500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 30000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 29500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 29000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 28500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 28000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 27500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 27000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 26500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 26000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 25500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 25000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 24500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 24000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 23500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 23000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 22500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 22000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 21500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 21000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 20500, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
	{ 20000, 7000, 10000, "talents=http://cn.battle.net/wow/en/tool/talent-calculator#Ya!002010", },
--]]
}
for index, profile in ipairs( stat_profiles ) do
	local total_stat, crit, haste, char_profile = unpack( profile )
	if not session.result[index] then
		session.base_iterations = 5000
		session.max_iterations = 50000
		session.min_stat = 0
		session.delta = 2000
		session.max_delta = 4000
		session.min_delta = 100
		session.prev_iterations = nil

		save_session()
		local total_agility = math.floor(5.521437321e-1 * total_stat + 12034.63797)
		log("Using agility %d for total stat %d", total_agility, total_stat)
		session.header = header .. ("\ngear_agility=%d"):format(total_agility) .. "\n" .. (char_profile or "")
		session.result[index] = climb_surf(crit, haste, total_stat)
		session.result[index].total_stat = total_stat
		session.result[index].start_crit = crit
		session.result[index].start_haste = haste
		session.profiles = {}
		save_session(true)
	end
end

local csv = io.open([[Sessions\]] .. session.name .. [[.csv]], "w")
csv:write("Agility", "\t")
csv:write("Total Stat", "\t")
csv:write("Crit", "\t")
csv:write("Haste", "\t")
csv:write("Mastery", "\t")
csv:write("DPS", "\t")
csv:write("Iterations", "\t")
--csv:write("Delta", "\t")
csv:write("Start Crit", "\t")
csv:write("Start Haste", "\t")
csv:write("\n")
for index, result in ipairs( session.result ) do
	local total_stat = result.total_stat
	local total_agility = math.floor(5.521437321e-1 * total_stat + 12034.63797)
	local mastery = total_stat - result.crit - result.haste
	csv:write(total_agility, "\t")
	csv:write(total_stat, "\t")
	csv:write(result.crit, "\t")
	csv:write(result.haste, "\t")
	csv:write(mastery, "\t")
	csv:write(result.dps, "\t")
	csv:write(result.iterations, "\t")
--	csv:write(result.delta, "\t")
	csv:write(result.start_crit, "\t")
	csv:write(result.start_haste, "\t")
	csv:write("\n")
end
csv:close()